import { createApp, type App } from 'vue'
import LoadingPage from './child/LoadingPage.vue'
import CatchingPage from './child/CatchingPage.vue'

export interface AppInitializationFn {
  (): Promise<boolean> | boolean | void
}
export interface AppVmFn {
  (): void
}

export class InitAdapter {
  private initFn: AppInitializationFn[] = []
  addInit(fn: AppInitializationFn) {
    this.initFn.push(async () => {
      const result = await fn()
      if (result === undefined) return true
      return result
    })
  }

  private appVmFn: AppVmFn = () => {}
  setAppVmFn(appVmFn: AppVmFn) {
    this.appVmFn = appVmFn
  }

  private loadingVm: App<Element> | null = null
  private async loading() {
    const div = document.createElement('div')
    div.setAttribute('id', 'app_loading')
    div.style.height = '100%'
    div.style.width = '100%'
    div.style.display = 'flex'
    div.style.justifyContent = 'center'
    div.style.alignItems = 'center'
    document.body.appendChild(div)
    this.loadingVm = createApp(LoadingPage)
    this.loadingVm.mount('#app_loading')
  }
  private stopLoading() {
    if (!this.loadingVm) return
    this.loadingVm.unmount()
    this.loadingVm = null
    let loadingDom = document.getElementById('app_loading')
    if (!loadingDom) return
    loadingDom.remove()
    loadingDom = null
  }
  private catchingVm: App<Element> | null = null
  private catching() {
    const div = document.createElement('div')
    div.setAttribute('id', 'app_catch')
    div.style.height = '100%'
    div.style.width = '100%'
    document.body.appendChild(div)
    this.catchingVm = createApp(CatchingPage)
    this.catchingVm.mount('#app_catch')
  }
  // private stopCatching() {
  //   if (!this.catchingVm) return
  //   this.catchingVm.unmount()
  //   this.catchingVm = null
  //   let catchingDom = document.getElementById('app_catch')
  //   if (!catchingDom) return
  //   catchingDom.remove()
  //   catchingDom = null
  // }

  init() {
    this.loading()
      .then(() => Promise.all(this.initFn.map((fn) => fn())))
      .then(() => this.stopLoading())
      .then(() => this.appVmFn())
      .catch((err) => {
        console.log('err', err)
        this.catching()
      })
  }
}
